#include <zconf.h>
#include "Service.h"
#include "FHE.h"
#include "EncryptedArray.h"

long w = 64;                // Hamming weight of secret key

FHEcontext *context;
EncryptedArray *ea;
FHESecKey *secretKey;


void test12() {


};


int main() {
    int len;
    long aaa = 2323;
    long aaa_j;
    cout << " a  :" << aaa << endl;
    const char *a_p = encrypt(aaa);
    len = strlen(a_p);
    char *a_p_copy = new char[len + 1];
    strcpy(a_p_copy, a_p);
    aaa_j = decrypt(a_p);
    cout << " a_j  :" << aaa_j << endl;
    long bbb = 4421;
    long bbb_j;
    cout << " bbb  :" << bbb << endl;
    const char *b_p = encrypt(bbb);
    len = strlen(b_p);
    char *b_p_copy = new char[len + 1];
    strcpy(b_p_copy, b_p);
    bbb_j = decrypt(b_p);
    cout << " bbb_j  :" << bbb_j << endl;
    const char *a_b_add_p = add(a_p_copy, b_p_copy);
    long a_b_add_j = decrypt(a_b_add_p);
    cout << " a_b_add_j  :" << a_b_add_j << endl;
    const char *a_b_mul_p = mul(a_p_copy, b_p_copy);
    long a_b_mul_j = decrypt(a_b_mul_p);
    cout << " a_b_mul_j  :" << a_b_mul_j << endl;
}






/*

void test0() {
    long m = 2 ,p = 715827883 ,r = 2;

    long c = 3;
    long w = 64;
    long L = 16;
   // m = FindM(128, L, c, p,3, 0, 0);
    FHEcontext *contexts;

    Ctxt *ctxts;
    EncryptedArray *eas;
    vector<ZZX> ptxts;

    fstream keyFile("iotest.txt", fstream::out | fstream::trunc);
    assert(keyFile.is_open());

    contexts = new FHEcontext(m, p, r);
    buildModChain(*contexts, L, c);  // Set the modulus chain

    // Output the FHEcontext to file
    writeContextBase(keyFile, *contexts);
    keyFile << *contexts << endl;

    FHESecKey sKeys(*contexts);
    const FHEPubKey &publicKey = sKeys;
    sKeys.GenSecKey(w); // A Hamming-weight-w secret key
    addSome1DMatrices(sKeys);// compute key-switching matrices that we need
    eas = new EncryptedArray(*contexts);

    long nslots = eas->size();
    keyFile << sKeys << endl;
    vector<ZZX> b;
    long p2r = eas->getContext().alMod.getPPowR();
    ZZX poly = RandPoly(0, to_ZZ(p2r)); // choose a random constant polynomial
    eas->decode(ptxts, poly);

    ctxts = new Ctxt(publicKey);
    eas->encrypt(*ctxts, publicKey, ptxts);
    eas->decrypt(*ctxts, sKeys, b);
    assert(ptxts.size() == b.size());
    for (long j = 0; j < nslots; j++) assert (ptxts[j] == b[j]);

    // output the plaintext
    keyFile << "[ ";
    for (long j = 0; j < nslots; j++) keyFile << ptxts[j] << " ";
    keyFile << "]\n";

    eas->encode(poly, ptxts);
    keyFile << poly << endl;
    keyFile << *ctxts << endl;
    keyFile << *ctxts << endl;


    keyFile.close();
}

void test1() {

    fstream keyFile("iotest.txt", fstream::in);

    // Read context from file
    unsigned long m1, p1, r1;
    vector<long> gens, ords;
    readContextBase(keyFile, m1, p1, r1, gens, ords);
    FHEcontext context(m1, p1, r1, gens, ords);
    keyFile >> context;

    FHESecKey secretKey(context);

    const FHEPubKey &publicKey = secretKey;


    keyFile >> secretKey;

    EncryptedArray ea(context);


    long nslots = ea.size();

    // Read the plaintext from file
    vector<ZZX> a;
    a.resize(nslots);

    seekPastChar(keyFile, '['); // defined in NumbTh.cpp
    for (long j = 0; j < nslots; j++) {
        keyFile >> a[j];

    }
    seekPastChar(keyFile, ']');
    cerr << "   ptxt matches input\n";

    // Read the encoded plaintext from file
    ZZX poly1, poly2;
    keyFile >> poly1;

    // Read ciperhtext from file
    Ctxt ctxt(publicKey);

    keyFile >> ctxt;


}*/